﻿using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;

namespace Taxhui.Utils.IOUtils
{
    public static class DataUtil
    {
        #region 压缩

        public static byte[] Compress(byte[] data, int offset, int lenght)
        {
            if (null == data)
                return null;
            if (data.Length < 1)
                return null;
            byte[] buffer = null;
            try
            {
                MemoryStream ms = new MemoryStream();
                GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true);
                zip.Write(data, offset, lenght);
                zip.Close();
                buffer = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(buffer, 0, buffer.Length);
                ms.Close();
            }
            catch { }
            return buffer;
        }

        #endregion 压缩

        #region 解压

        public static byte[] Decompress(byte[] data)
        {
            if (null == data)
                return null;
            if (data.Length < 1)
                return null;
            byte[] buffer = null;
            try
            {
                MemoryStream ms = new MemoryStream(data);
                GZipStream zip = new GZipStream(ms, CompressionMode.Decompress, true);
                MemoryStream msreader = new MemoryStream();
                buffer = new byte[0x1000];
                while (true)
                {
                    int reader = zip.Read(buffer, 0, buffer.Length);
                    if (reader <= 0)
                    {
                        break;
                    }
                    msreader.Write(buffer, 0, reader);
                }
                zip.Close();
                ms.Close();
                msreader.Position = 0;
                buffer = msreader.ToArray();
                msreader.Close();
            }
            catch { }
            return buffer;
        }

        #endregion 解压

        #region 字节转换

        /// <summary>
        /// 16进制字符串转换成byte[]
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] StrToByte(string str)
        {
            byte[] data = new byte[str.Length / 2];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = byte.Parse(str.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
            }
            return data;
        }

        /// <summary>
        /// Byte[]转换16进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ByteToStr(byte[] data)
        {
            if (null == data)
                return "";
            string retStr = "";
            for (int i = 0; i < data.Length; i++)
            {
                retStr += data[i].ToString("X2");
            }
            return retStr;
        }

        /// <summary>
        /// 检查转换密钥
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="len">密钥长度（字节）</param>
        /// <param name="sEncode">编码</param>
        /// <returns></returns>
        internal static byte[] GetKeyByte(string key, int len, Encoding sEncode)
        {
            if (string.IsNullOrEmpty(key))
                return new byte[len];
            if (key.Length < len)
                key = key.PadLeft(len, '0');
            if (key.Length > len)
                key = key.Substring(0, len);
            return sEncode.GetBytes(key);
        }

        internal static bool CheckData(byte[] data, ref Encoding sEncode)
        {
            if (null == data)
                return false;
            if (data.Length < 1)
                return false;
            sEncode = sEncode ?? Encoding.UTF8;
            return true;
        }

        #endregion 字节转换

        #region 计算文件MD5

        public static string ComputeFileMD5(string path)
        {
            try
            {
                FileStream fs = new FileStream(path, FileMode.Open);
                var cryptor = MD5.Create();
                byte[] mdByte = cryptor.ComputeHash(fs);
                fs.Close();
                fs.Dispose();
                cryptor.Dispose();
                return ByteToStr(mdByte);
            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion 计算文件MD5
    }
}